﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Globalization;
using SLControlLibrary.Resources.Controls.Calendar.Common;
using SLControlLibrary.Resources.Controls.Calendar.ClassicCalendar;
using SLControlLibrary.Resources.Controls.Calendar.Buttons;
using SLControlLibrary.Resources.Controls.Calendar.ClassicCalendar.BusinessObjects;
using SLControlLibrary.Resources.Controls.Calendar.ClassicCalendar.DataAccess;

namespace SLControlLibrary.Resources.Controls.Calendar.ExtendedCalendar
{
    public class ucCalendar : Control
    {
        #region Dependency Variables
        private static readonly DependencyProperty DescProperty = DependencyProperty.Register("Desc", typeof(string), typeof(ucCalendar), new PropertyMetadata(DateTime.Today.Year.ToString()));
        private static readonly DependencyProperty MonthHeightProperty = DependencyProperty.Register("MonthHeight", typeof(double), typeof(ucCalendar), new PropertyMetadata(210D, new PropertyChangedCallback(MonthHeight_Changed)));
        private static readonly DependencyProperty MonthWidthProperty = DependencyProperty.Register("MonthWidth", typeof(double), typeof(ucCalendar), new PropertyMetadata(210D, new PropertyChangedCallback(MonthWidth_Changed)));
        private static readonly DependencyProperty MonthSpanProperty = DependencyProperty.Register("MonthSpan", typeof(int), typeof(ucCalendar), new PropertyMetadata(1, new PropertyChangedCallback(MonthSpan_Changed)));
        private static readonly DependencyProperty MonthsInViewProperty = DependencyProperty.Register("MonthsInView", typeof(string), typeof(ucCalendar), new PropertyMetadata(null));
        private static readonly DependencyProperty WeekHeaderForegroundProperty = DependencyProperty.Register("WeekHeaderForeground", typeof(SolidColorBrush), typeof(ucCalendar), new PropertyMetadata(new SolidColorBrush(Colors.Black)));
        #endregion

        #region Dependency Properties
        public string Desc
        {
            get { return (string)this.GetValue(DescProperty); }
            set { SetValue(DescProperty, value); }
        }
        public double MonthHeight
        {
            get { return (double)this.GetValue(MonthHeightProperty); }
            set { SetValue(MonthHeightProperty, value); }
        }
        public double MonthWidth
        {
            get { return (double)this.GetValue(MonthWidthProperty); }
            set { SetValue(MonthWidthProperty, value); }
        }
        public int MonthSpan
        {
            get { return (int)this.GetValue(MonthSpanProperty); }
            set { SetValue(MonthSpanProperty, value); }
        }
        public string MonthsInView
        {
            get { return (string)this.GetValue(MonthsInViewProperty); }
            set { SetValue(MonthsInViewProperty, value); }
        }
        public SolidColorBrush WeekHeaderForeground
        {
            get { return (SolidColorBrush)this.GetValue(WeekHeaderForegroundProperty); }
            set { SetValue(WeekHeaderForegroundProperty, value); }
        }
        #endregion 

        #region Depedency Events
        #region MonthHeight_Changed
        private static void MonthHeight_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucCalendar).OnMonthHeight_Changed(e);
        }
        #endregion

        #region MonthWidth_Changed
        private static void MonthWidth_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
           (sender as ucCalendar).OnMonthWidth_Changed(e);
        }
        #endregion

        #region MonthSpan_Changed
        private static void MonthSpan_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
           (sender as ucCalendar).OnMonthSpan_Changed(e);
        }
        #endregion
        #endregion

        #region Variables
        private int _CurrentIndex = 1;
        private int _CurrentYear = 0;
        private double _LastLeft = 0;
        private StackPanel spCollection;
        private StackPanel spLegend;
        private Canvas cnvContainer;
        private Storyboard mvStkpLeft;
        private Storyboard mvStkpRight;
        private SplineDoubleKeyFrame spldkf_left;
        private SplineDoubleKeyFrame spldkf_right;
        private ucCalendarButton btnLeftMonth;
        private ucCalendarButton btnRightMonth;
        private ucCalendarButton btnLeftYear;
        private ucCalendarButton btnRightYear;
        #endregion 
        
        #region Properties
        public double MoveLeftDistance
        {
            get  { return (MonthWidth + 6) * MonthSpan;  }
        }
        public string CalendarType { get; set; }
        #endregion

        #region Constructor
        public ucCalendar()
        {
            DefaultStyleKey = typeof(ucCalendar);
        }
        #endregion

        #region Events
        #region btnMoveMonthLeft_MouseLeftButtonUp
        private void btnMoveMonthLeft_MouseLeftButtonUp(System.Object sender, RoutedEventArgs e)
        {
            if (!((_CurrentIndex - MonthSpan) < 0))
            {
                _CurrentIndex = _CurrentIndex - MonthSpan;
                MoveRight();
            }

            if (_CurrentIndex >= 10)
                MonthsInView = Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), _CurrentIndex.ToString(), false).ToString() + ", " + _CurrentYear + " - " + Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), 12.ToString(), false).ToString() + ", " + _CurrentYear;
            else
                MonthsInView = Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), _CurrentIndex.ToString(), false).ToString() + ", " + _CurrentYear + " - " + Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), (_CurrentIndex + 2).ToString(), false).ToString() + ", " + _CurrentYear;
        }
        #endregion

        #region btnMoveMonthRight_MouseLeftButtonUp
        private void btnMoveMonthRight_MouseLeftButtonUp(System.Object sender, RoutedEventArgs e)
        {
            if ((_CurrentIndex + MonthSpan) > 12)
            {
                _LastLeft = 1;
                _CurrentIndex = 1;
                MoveRight();
            }
            else
            {
                _CurrentIndex = _CurrentIndex + MonthSpan;
                MoveLeft();
            }

            if (_CurrentIndex >= 10)
                MonthsInView = Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), _CurrentIndex.ToString(), false).ToString() + ", " + _CurrentYear + " - " + Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), 12.ToString(), false).ToString() + ", " + _CurrentYear;
            else
                MonthsInView = Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), _CurrentIndex.ToString(), false).ToString() + ", " + _CurrentYear + " - " + Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), (_CurrentIndex + 2).ToString(), false).ToString() + ", " + _CurrentYear;
        }
        #endregion 

        #region btnMoveYearLeft_MouseLeftButtonUp
        private void btnMoveYearLeft_MouseLeftButtonUp(System.Object sender, RoutedEventArgs e)
        {
            _CurrentYear--;
            PopulateCalendar();
        }
        #endregion

        #region btnMoveYearRight_MouseLeftButtonUp
        private void btnMoveYearRight_MouseLeftButtonUp(System.Object sender, RoutedEventArgs e)
        {
            _CurrentYear++;
            PopulateCalendar();
        }
        #endregion 

        #region cOpts_OptionsLoaded
        private void cOpts_OptionsLoaded(object sender, SLControlLibrary.Resources.Controls.Calendar.ClassicCalendar.Events.OptionsLoadedEventArgs e)
        {
            foreach (DaySelection _Opt in e.SelectionCollection)
            {
                Rectangle _rct = new Rectangle();
                _rct.Fill = _Opt.Color;
                _rct.Height = 10;
                _rct.Width = 10;
                TextBlock _txt = new TextBlock();
                _txt.Text = _Opt.Desc;
                _txt.Margin = new Thickness(5, 4, 15, 0);
                _txt.TextAlignment = TextAlignment.Center;

                spLegend.Children.Add(_rct);
                spLegend.Children.Add(_txt);
            }
        }
        #endregion
        #endregion

        #region Methods
        #region OnApplyTemplate
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _CurrentYear = DateTime.Now.Year;

            spCollection = (StackPanel)base.GetTemplateChild("spCollection");
            spLegend = (StackPanel)base.GetTemplateChild("spLegend");
            cnvContainer = (Canvas)base.GetTemplateChild("cnvContainer");
            mvStkpLeft = (Storyboard)base.GetTemplateChild("mvStkpLeft");
            mvStkpRight = (Storyboard)base.GetTemplateChild("mvStkpRight");
            spldkf_left = (SplineDoubleKeyFrame)base.GetTemplateChild("spldkf_left");
            spldkf_right = (SplineDoubleKeyFrame)base.GetTemplateChild("spldkf_right");
            btnLeftMonth = (ucCalendarButton)base.GetTemplateChild("btnLeftMonth");
            btnRightMonth = (ucCalendarButton)base.GetTemplateChild("btnRightMonth");
            btnLeftYear = (ucCalendarButton)base.GetTemplateChild("btnLeftYear");
            btnRightYear = (ucCalendarButton)base.GetTemplateChild("btnRightYear");

            if (spCollection == null) return;
            if (spLegend == null) return;
            if (cnvContainer == null) return;
            if (mvStkpLeft == null) return;
            if (mvStkpRight == null) return;
            if (spldkf_left == null) return;
            if (spldkf_right == null) return;
            if (btnLeftMonth == null) return;
            if (btnRightMonth == null) return;
            if (btnLeftYear == null) return;
            if (btnRightYear == null) return;

            btnLeftMonth.Click += new RoutedEventHandler(btnMoveMonthLeft_MouseLeftButtonUp);
            btnRightMonth.Click += new RoutedEventHandler(btnMoveMonthRight_MouseLeftButtonUp);
            btnLeftYear.Click += new RoutedEventHandler(btnMoveYearLeft_MouseLeftButtonUp);
            btnRightYear.Click += new RoutedEventHandler(btnMoveYearRight_MouseLeftButtonUp);

            PopulateCalendar();
        }
        #endregion 

        #region PopulateCalendar
        private void PopulateCalendar()
        {
            this.Desc = _CurrentYear.ToString();
            spCollection.Children.Clear();
            spLegend.Children.Clear();

            for (int i = 1; i <= 12; i++)
            {
                ClassicCalendar.ucCalendar _Calendar = new ClassicCalendar.ucCalendar();
                _Calendar._CurrentYear = _CurrentYear;
                _Calendar._CurrentMonth = i;
                _Calendar.ControlHeight = MonthHeight;
                _Calendar.ControlWidth = MonthWidth;
                _Calendar.AllowMonthNavigation = false;
                _Calendar.DateView = Enumerations.CurrentDateView.Month;
                _Calendar.DisplayMode = Enumerations.DisplayMode.Display;
                _Calendar.Margin = new Thickness(3, 0, 3, 0);

                spCollection.Children.Add(_Calendar);
            }

            CalendarOptions _cOpts = new CalendarOptions();
            _cOpts.OptionsLoaded += new SLControlLibrary.Resources.Controls.Calendar.ClassicCalendar.Events.OptionsLoadedHandler(cOpts_OptionsLoaded);
            _cOpts.RequestXML(CalendarType);            

            MonthsInView = Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), _CurrentIndex.ToString(), false).ToString() + ", " + _CurrentYear.ToString() + " - " + Enum.Parse(typeof(Enumerations.MonthsInYearLongDesc), (_CurrentIndex + 2).ToString(), false).ToString() + ", " + _CurrentYear.ToString();
        }
        #endregion 

        #region MoveLeft
        private void MoveLeft()
        {
            if ((this.cnvContainer.ActualWidth < ((this.spCollection.Children.Count * MoveLeftDistance) + _LastLeft)))
            {
                _LastLeft -= MoveLeftDistance;
                SplineDoubleKeyFrame frame = spldkf_left;
                frame.Value = _LastLeft;
                mvStkpLeft.Begin();
            }
        }
        #endregion

        #region MoveRight
        private void MoveRight()
        {
            if ((_LastLeft < 0))
            {
                _LastLeft += MoveLeftDistance;
                SplineDoubleKeyFrame frame = spldkf_right;
                frame.Value = _LastLeft;
                mvStkpRight.Begin();
            }
            else
            {
                _LastLeft = 0;
                SplineDoubleKeyFrame frame = spldkf_right;
                frame.Value = _LastLeft;
                mvStkpRight.Begin();
            }
        }
        #endregion 

        #region OnMonthHeight_Changed
        protected virtual void OnMonthHeight_Changed(DependencyPropertyChangedEventArgs e)
        {
            MonthHeight = double.Parse(e.NewValue.ToString());
        }
        #endregion

        #region OnMonthWidth_Changed
        protected virtual void OnMonthWidth_Changed(DependencyPropertyChangedEventArgs e)
        {
            MonthWidth = double.Parse(e.NewValue.ToString());   
        }
        #endregion

        #region OnMonthSpan_Changed
        protected virtual void OnMonthSpan_Changed(DependencyPropertyChangedEventArgs e)
        {
            MonthSpan = Int32.Parse(e.NewValue.ToString());
        }
        #endregion
        #endregion
    }
}
